#ifndef _Ape__MT_Thread_h
#define _Ape__MT_Thread_h

#include <Ape/Object.h>
#include <Ape/String.h>
#include <Ape/Uuid.h>
#include <Ape/EventModel/Event.h>
#include <Ape/Collections/Map.h>

#if defined(APE_USES_PTHREAD)
#include <pthread.h>
#endif

namespace Ape {
	class Exception;
	
	namespace MT {
		using namespace Ape;
		using namespace Ape::EventModel;
		using namespace Ape::Collections;
		
		void* thread_dispatch (void* param);
		
		class Thread : public Object {
			TYPE_NAME ("Ape::MT::Thread")
			friend void* thread_dispatch (void* param);
		public:
			const Uuid ID;
			const String Name;
		private:
			Exception* m_Exception;
#if defined(APE_USES_PTHREAD)
			pthread_t m_Handle;
#endif
			EventArgs* m_Args;
			bool m_Running;
			
			Thread (const Thread& other);
			
			void __Start (void* handle);
		public:
			Event<EventArgs> OnStart;
			
			//Thread();
			Thread (const String name = L"Thread-" + Uuid::Generate().ToString() );
			virtual ~Thread();
			
			void Start();
			void Start (EventArgs& ea);
			void Join();
			
			Exception* get_Exception() const;
			bool IsOk() const;
			bool IsRunning() const;
			
			virtual const Ape::String ToString() const;
			
			const Ape::Uuid& get_ID() const;
			
			static Thread* Current();
			static Thread* ByID(const Ape::Uuid& id);
			static void Sleep(size_t microSecs);
		};
	}
}

#endif // _Ape__MT_Thread_h
